package cn.hloger.spider.utils;

import cn.hutool.crypto.digest.MD5;
import org.springframework.stereotype.Service;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class UrlUtils {

    /**
     * 拼接Url
     *
     * @param params
     * @param encode
     * @return
     */
    public static String lingUrlString(Map<String, Object> params, boolean encode) {
        //过滤不签名的选项
        params = paraFilter(params);

        List<String> keys = new ArrayList<String>(params.keySet());
        Collections.sort(keys);
        String prestr = "";

//        String charset = params.get(BaseConstant.INPUT_CHARSET);
        for (int i = 0; i < keys.size(); i++) {
            String key = keys.get(i);
            String value = params.get(key).toString();
            if (encode) {
                try {
                    value = URLEncoder.encode(value, "UTF-8");
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
            }
            if (i == keys.size() - 1) {// 拼接时，不包括最后一个&字符
                prestr = prestr + key.toLowerCase() + "=" + value;
            } else {
                prestr = prestr + key.toLowerCase() + "=" + value + "&";
            }
        }

        return prestr;
    }

    /**
     * 除去数组中的空值和签名参数
     *
     * @param sArray 签名参数组
     * @return 去掉空值与签名参数后的新签名参数组
     */
    public static Map<String, Object> paraFilter(Map<String, Object> sArray) {
        Map<String, Object> result = new HashMap<String, Object>();
        if (sArray == null || sArray.size() <= 0) {
            return result;
        }
        for (String key : sArray.keySet()) {
            //数组集合类型不参与签名
            boolean b = sArray.get(key) instanceof Object[] || sArray.get(key) instanceof List;
            if (b) {
                continue;
            }
            String value = sArray.get(key).toString();
            if (value == null || value.equals("")
                    || key.equalsIgnoreCase("sign")
            ) {
                continue;
            }
            result.put(key, value);
        }
        return result;
    }

    /**
     * 给数据签名
     * <p>
     * 签名参数组
     *
     * @return 去掉空值与签名参数后的新签名参数组
     */
    public static String sgin(String data, String key) {
        String result = "";
        result = data + "&key=" + key;
        String sgin = MD5.create().digestHex16(result);
        return sgin.toUpperCase();
    }

    /**
     * 给数据签名
     * <p>
     * 签名参数组
     *
     * @return 去掉空值与签名参数后的新签名参数组
     */
    public static String getSgin(Map<String, Object> params, String key) {
        String urlStr = lingUrlString(params, false);
        System.out.println(urlStr);
        return sgin(urlStr, key);
    }


    /**
     * {
     * "AppKey": "123456",
     * "UserCode": "teacher1",
     * "UserTrueName": "测试",
     * "GradeId": 1,
     * "Sign": "0F80595291358A3E050C5E1F46DFCD40",
     * "CourseId": 2,
     * "NonceStr": "greeteryer",
     * "UserTypeId": 1
     * }
     *
     * @param args
     */


    public static void main(String[] args) {
        Map map = new HashMap();
        map.put("AppKey", "98169");
        map.put("UserCode", "student233");
        map.put("CourseId", 12);
        map.put("KnowledgePointIds", new Long[]{10003L});
        map.put("NonceStr", "asassfdfdfdf111");
        String appsecret = getSgin(map, "testapitoken");
        System.out.println(appsecret);
    }

//    public static void main(String[] args) {
//        Map map = new HashMap();
//        map.put("AppKey","98169");
//        map.put("UserCode","student233");
//        map.put("UserTrueName","天有对接学生2");
//        map.put("GradeId",6);
//        map.put("Sign","198C42562A262C9AC34A147E05E26B74");
//        map.put("CourseId",0);//学科id，
//        map.put("NonceStr","调用测试33");
//        map.put("UserTypeId",2);
//        String string = lingUrlString(map, false);
//        System.out.println(string);
//        String sgin = sgin(string, "testapitoken");
//        System.out.println(sgin);
//
//        String appsecret = getSgin(map, "testapitoken");
//        System.out.println(appsecret);
//    }
}
